#include "StdAfx.h"
#include "FileDB.h"
#include <QDirIterator>
#include <QFileInfo>
#include <QApplication>

FileDB::FileDB()
{

}

FileDB::~FileDB()
{

}

bool FileDB::GenerateFileDB(const QString& path)
{
	rootDir = path;
	ParsePath(path,"");	
	return true;
}

void FileDB::ParsePath( const QString& path, QString relativePath )
{
	QDirIterator it(path, QDir::Dirs|QDir::Files|QDir::NoDotAndDotDot);

	int pathId = pathDB.size();
	pathDB.push_back(relativePath);

	while (it.hasNext()) 
	{
		it.next();
		QFileInfo fileInfo = it.fileInfo();
		if (fileInfo.isDir())
		{
			ParsePath(fileInfo.filePath(),relativePath+"\\"+fileInfo.fileName());
		}
		else
		{
			FileIntoItem item;
			item.filename = fileInfo.fileName();
			item.pathId = pathId;
			item.size = fileInfo.size();

			fileDB.push_back(item);
		}
	}
}

const FileDB::PathInfoTableType& FileDB::GetPathInfoTable()
{
	return pathDB;
}

const FileDB::FileInfoTableType& FileDB::GetFileInfoTable()
{
	return fileDB;
}

void FileDB::SetPathTable(const seven::PathTable* table )
{
	pathDB.clear();
	if (table)
	{
		for (int i = 0; i!=table->item_size(); ++i)
		{
			pathDB.push_back(table->item(i).path_value().c_str());
		}
	}
}

void FileDB::SetFileTable(const seven::FileTable* table )
{
	fileDB.clear();
	if (table)
	{
		for (int i = 0; i!=table->item_size(); ++i)
		{
			const seven::FileItem& fileItem = table->item(i);

			FileIntoItem item;
			item.filename = fileItem.file_name().c_str();
			item.pathId = fileItem.path_id();
			item.size = fileItem.file_size();

			fileDB.push_back(item);
		}
	}
		
}

void FileDB::GetPathTable( seven::PathTable * table )
{
	if (table)
	{
		for (int i = 0; i!=pathDB.size(); ++i)
		{
			seven::PathItem* item = table->add_item();
			item->set_path_id(i);
			item->set_path_value(QString2String(pathDB[i]));
		}
	}
}

void FileDB::GetFileTable( seven::FileTable * table )
{
	if (!table)
	{
		return;
	}

	for (int i = 0; i!=fileDB.size(); ++i)
	{
		const FileDB::FileIntoItem& fileInfoItem = fileDB[i];
		seven::FileItem* item = table->add_item();
		item->set_file_id(i);
		item->set_file_name(QString2String(fileInfoItem.filename));
		item->set_file_size(fileInfoItem.size);
		item->set_path_id(fileInfoItem.pathId);
	}
}

QString FileDB::GetFileRelativePath( int fileId )
{
	if (fileId < fileDB.size())
	{
		int pathId = fileDB[fileId].pathId;
		return pathDB[pathId] + "\\" + fileDB[fileId].filename; 
	}
	return "";
}


bool FileDB::CreateFile( int fileId )
{
	QString fullPath = GetFilePath(fileId);
	QFileInfo info(fullPath);
	QDir dir = info.absoluteDir();
	if (!dir.exists())
	{
		QString path = dir.path();
		if (!dir.mkpath(dir.path()))
		{
			QFile outFile(fullPath);
			if (!outFile.open(QIODevice::WriteOnly)) {
				Show(outFile.errorString());
				int size = GetFileSize(fileId);
				return outFile.resize(size);
			}
			return true;
		} else
		{
			return false;
		}
	}	
	return true;
}

int FileDB::GetFileSize( int fileId )
{
	return fileDB[fileId].size;
}

bool FileDB::Write( int fileId,int begin,const char* buff,int size )
{
	QString fullPath = GetFilePath(fileId);
	QFile outFile(fullPath);
	if (!outFile.open(QIODevice::WriteOnly)) {
		Show(outFile.errorString());
		return false;
	}
	if(outFile.size() < begin + size)
	{
		if (outFile.isWritable())
		{
			if(outFile.seek(begin))
			{
				if(outFile.write(buff,size))
					return true;
			}
		}
	}
	return false;
}

QString FileDB::GetFilePath( int fileId )
{
	QString filename = GetFileRelativePath(fileId);
	QString fullPath = rootDir  + filename;
	fullPath = QDir::toNativeSeparators(fullPath);
	return fullPath;
}

void FileDB::SetPath( QString path )
{
	rootDir = path;
}

bool FileDB::CreateDir( int pathId )
{
	QString path = pathDB[pathId];
	QString fullPath = rootDir  + path;
	fullPath = QDir::toNativeSeparators(fullPath);
	QDir dir(fullPath);
	if (!dir.exists())
	{
		QString path = dir.path();
		if (!dir.mkpath(dir.path()))
		{
			return false;
		}
	}
	return true;
}

bool FileDB::CreateDirs()
{
	for(size_t i = 0; i!=pathDB.size(); ++i)
	{
		if (!CreateDir(i))
		{
			return false;
		}
	}
	return true;
}
